package com.ttflutter.tkvideodownloader;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.List;

/**
 * @author Afra55
 * @date 2020/5/31
 * A smile is the best business card.
 */
public class Sign {
    static boolean checkHook(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            List<ApplicationInfo> applicationInfoList  = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
            for(ApplicationInfo applicationInfo : applicationInfoList) {
                if(applicationInfo.packageName.equals("de.robv.android.xposed.installer")) {
                    return true;
                }
            }

            try {
                throw new Exception("checkhook");
            } catch(Exception e) {
                e.printStackTrace();
                for (StackTraceElement stackTraceElement : e.getStackTrace()) {
                    if(stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge")
                            && stackTraceElement.getMethodName().equals("main")) {
                        return true;
                    }
                    if(stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge")
                            && stackTraceElement.getMethodName().equals("handleHookedMethod")) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    static boolean checkRoot(Context context) {
        try {
            if (new File("/system/app/Superuser.apk").exists())
                return true;

            List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
            for(PackageInfo pack : packages) {
                //Log.d("checkRoot", pack.packageName);
                if (pack.packageName.equals("eu.chainfire.supersu"))
                    return true;
            }

            String[] paths = {"/sbin/su", "/system/bin/su",
                    "/system/xbin/su", "/system/bin/failsafe/su"};
            for (String path : paths) {
                if (new File(path).exists()) return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }


    private static String getProp(Context ctx, String propName) {
        try {
            ClassLoader cl = ctx.getClassLoader();
            Class<?> clz = cl.loadClass("android.os.properties");
            Method getProp = clz.getMethod("get", String.class);
            Object[] params = {propName};
            return (String) getProp.invoke(clz, params);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    static boolean checkEMU(Context context) {
        try {
            if ("goldfish".equals(getProp(context, "ro.hardware")))
                return true;
            if ("1".equals(getProp(context, "ro.kernel.qemu")))
                return true;
            if ("generic".equals(getProp(context, "ro.product.device")))
                return true;

            if (Build.MANUFACTURER.contains("Genymotion"))
                return true;
            if (Build.DEVICE.startsWith("generic"))
                return true;
            if (Build.MODEL.contains("sdk"))
                return true;

//            if (new File("/init.goldfish.rc").exists())
//                return true;
//            if (new File("/system/bin/qemud").exists())
//                return true;

            try {
                BufferedReader cpuInfoReader = new BufferedReader(new FileReader("/proc/cpuinfo"));
                String line;
                while ((line = cpuInfoReader.readLine()) != null) {
                    if (line.contains("Goldfish"))
                        return true;
                }
            } catch (Exception e) {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }


    private static  boolean  portused = false;
    static void checkBadGuyPort(Activity activity) {
        final int port_ = 23946;
        try {
            new Thread() {
                @Override
                public void run() {
                    try {
                        InetAddress addr = InetAddress.getByName("127.0.0.1");
                        Socket sock = new Socket(addr, port_);
                        portused = true;
                    } catch (Throwable e) {
                        e.printStackTrace();
                        portused = false;
                    }

                    try {
                        activity.runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                try {
                                    if (portused) {
                                        Toast.makeText(activity,"Check network port 23946 Used, Please don't do this!", Toast.LENGTH_LONG).show();
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    static boolean isBadGuyDebugger(Context context) {
        try {
            if ((context.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                return true;
            }
            return android.os.Debug.isDebuggerConnected();
        } catch (Exception e) {
            return false;
        }
    }

    private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

     static String signatureMD5(Signature[] signatures) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            if (signatures != null) {
                for (Signature s : signatures)
                    digest.update(s.toByteArray());
            }
            return toHexString(digest.digest());
        } catch (Exception e) {
            return "";
        }
    }

    private static String toHexString(byte[] b) {
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
            sb.append(HEX_DIGITS[b[i] & 0x0f]);
        }
        return sb.toString();
    }

}
